﻿using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.IdentityModel.Logging;
using PLCS.App.Shared.Events;
using PLCS.Application.Contracts.StationApp.Dtos;
using PLCS.Client.Service.Client;
using PLCS.Domain.Shared.Enums;
using PLCS.Shared.Common.Constant;
using RestSharp;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace PLCS.App.Shared.Views.UserControls.Chlidren;

/// <summary>
/// Station.xaml 的交互逻辑
/// </summary>
public partial class Station : UserControl, ICommandSource
{
    #region Properties

    //private HubConnection hubConnection;

    private Border border = new Border();

    //Webapi客户端
    public HttpRestClient restClient = new();

    //private RequestParam requestParam;
    private SolidColorBrush bg;

    /// <summary>
    /// 工位名称
    /// </summary>
    public string SName
    {
        get { return (string)GetValue(SNameProperty); }
        set { SetValue(SNameProperty, value); }
    }

    public static readonly DependencyProperty SNameProperty =
        DependencyProperty.Register("SName", typeof(string), typeof(Station), new PropertyMetadata("S101"));

    /// <summary>
    /// 工位旋转角度
    /// </summary>
    public int Angle
    {
        get { return (int)GetValue(AngleProperty); }
        set { SetValue(AngleProperty, value); }
    }

    public static readonly DependencyProperty AngleProperty =
        DependencyProperty.Register("Angle", typeof(int), typeof(Station), new PropertyMetadata(0));

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof(ICommand), typeof(Station), new UIPropertyMetadata(null));

    public object CommandParameter
    {
        get { return (object)GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CommandParameter.  This enables animation,styling,binding,etc...
    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(Station), new UIPropertyMetadata(null));

    /// <summary>
    /// 强制输入事件和属性来自FrameworkElement
    /// </summary>
    public IInputElement CommandTarget
    {
        get { return (IInputElement)GetValue(CommandTargetProperty); }
        set { SetValue(CommandTargetProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CommandTarget.  This enables animation,etc...
    public static readonly DependencyProperty CommandTargetProperty =
        DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(Station), new UIPropertyMetadata(null));

    /// <summary>
    /// 是否有无托盘
    /// </summary>
    public YesNo HaveStatus
    {
        get { return (YesNo)GetValue(HaveStatusProperty); }
        set { SetValue(HaveStatusProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Seat.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HaveStatusProperty =
        DependencyProperty.Register("HaveStatus", typeof(YesNo), typeof(Station), new PropertyMetadata(YesNo.否, new PropertyChangedCallback(OnHaveChanged)));

    #endregion Properties

    #region Constructor

    public Station()
    {
        InitializeComponent();
        Cursor = Cursors.Hand;
        SizeChanged += Station_SizeChange;
        //this.Loaded += Station_Loaded;
        //Task.Run(UIChange);
    }

    #endregion Constructor

    #region Event

    //是否有托盘值改变触发
    private static void OnHaveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as Station).RefreshHaveStatus();

    /// <summary>
    /// 加载事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private async void Station_Loaded(object sender, RoutedEventArgs e)
    {
        await using HubConnection hubConnection = new HubConnectionBuilder().WithUrl(AddressManager.Address + AddressManager.StationHub).Build();
        hubConnection.On<string, YesNo>("ChangeStatus", async (sname, status) =>
        {
            await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                if (sname == SName)
                    if (status != HaveStatus) HaveStatus = status;
            }), System.Windows.Threading.DispatcherPriority.Background);
        });
        if (hubConnection.State != HubConnectionState.Connected)
        {
            await hubConnection.StartAsync();
            await hubConnection.InvokeAsync("InitalStatus", SName);
        }
    }

    /// <summary>
    /// 重载鼠标左击时触发事件
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonDown(e);
        //_eventAggregator.GetEvent<StationEvent>().Publish(SName);
        var command = Command;
        var parameter = CommandParameter;
        var target = CommandTarget;

        var routedCmd = command as RoutedCommand;
        if (routedCmd != null && routedCmd.CanExecute(parameter, target))
        {
            routedCmd.Execute(parameter, target);
        }
        else if (command != null && command.CanExecute(parameter))
        {
            command.Execute(parameter);
        }
    }

    /// <summary>
    /// usercontrol size changed event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    /// <exception cref="NotImplementedException"></exception>
    private void Station_SizeChange(object sender, SizeChangedEventArgs e)
    {
        LayoutCanvas.Children.Clear();
        ToolTip = $"工位：{SName}";
        border = new Border();
        border.Width = ActualWidth;
        border.Height = ActualHeight;
        border.Background = Background ?? Brushes.DimGray;
        border.BorderThickness = new Thickness(1);
        border.Margin = new Thickness(2, 2, 2, 2);
        LayoutCanvas.Children.Add(border);
    }

    #endregion Event

    #region Method

    /// <summary>
    /// 刷新是否有货/托盘
    /// </summary>
    public void RefreshHaveStatus() => Dispatcher.Invoke(new Action(delegate
    {
        //颜色 要 改成可以配置： 空 颜色 满颜色 ，暂时写死
        border.Background = HaveStatus == YesNo.否 ? Brushes.DimGray : new SolidColorBrush(Color.FromRgb(11, 112, 253));
    }));

    /// <summary>
    /// UIChange
    /// </summary>
    private async void UIChange()
    {
        await Dispatcher.BeginInvoke(new Action(async () =>
        {
            try
            {
                while (true)
                {
                    if (string.IsNullOrWhiteSpace(SName))
                    {
                        await Task.Delay(TimeSpan.FromSeconds(5));
                        continue;
                    }
                    if (SName == "W401")
                    {
                    }
                    RequestParam requestParam = new RequestParam(Method.Post, $"station/bySName?name={SName}");
                    var apiResponse = await restClient.ExecuteAsync<StationDto>(requestParam);
                    var model = apiResponse.Data;
                    if (model == null)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(5));
                        continue;
                    }
                    HaveStatus = model.HaveStatus;
                    await Task.Delay(TimeSpan.FromSeconds(1));
                }
            }
            catch (Exception ex)
            {
                ex = new Exception($"Station{SName}更改界面方法发生错误：{ex.Message}");
                //LogHelper.LogExceptionMessage(ex);
                await Task.Delay(5000);
            }
        }), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
    }

    #endregion Method
}